package com.cyf.app;

import com.cyf.app.network.bean.*;
import com.cyf.app.network.bean.car.*;
import com.cyf.app.service.AppService;
import com.cyf.app.service.bean.IllegalQuery;
import com.cyf.db.bean.Adminpara;
import com.cyf.util.BasicProperties;
import com.cyf.web.network.bean.RespResult;
import com.cyf.web.service.WebService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

@Controller
@RestController
@Api("APP相关api")
@RequestMapping(value = "app")
public class AppHttpController {

    private static final Logger logger = LoggerFactory.getLogger(AppHttpController.class);
    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    @Autowired
    private AppService appService;
    @Autowired
    private BasicProperties basicProperties;
    @Autowired
    private WebService webService;

    @ApiOperation(value = "发送短信验证码")
    @PostMapping(value = "/appRegSms")
    public AppRegSmsRsp sendSms(@RequestParam String mobile) {
        AppRegSmsReq req = new AppRegSmsReq();
        req.setMobile(mobile);
        return appService.sendSms(req);
    }

    @ApiOperation(value = "登录")
    @PostMapping(value = "/login")
    public AppLoginRsp login(@RequestParam String mobile,
                             @RequestParam int smsCode) {
        AppLoginReq req = new AppLoginReq();
        req.setMobile(mobile);
        req.setSmsCode(smsCode);
        return appService.login(req);
    }

    @ApiOperation(value = "退出")
    @PostMapping(value = "/logout")
    public AppLogoutRsp logout(@RequestParam String token) {
        AppLogoutReq req = new AppLogoutReq();
        req.setToken(token);
        return appService.logout(req);
    }

    @ApiOperation(value = "添加车辆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "车牌号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "color", value = "颜色", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "brand", value = "品牌", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkTime", value = "年检时间", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "registerTime", value = "注册时间", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "isEnergy", value = "是否是新能源 1是 0否", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "mileage", value = "行驶里程", required = false, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/addCar")
    public AppAdCarRsp addCar(@RequestParam String token,@RequestParam(required = false) String checkTime,
                              @RequestParam String plate,@RequestParam(required = false) String registerTime,
                              @RequestParam(required = false) String type,@RequestParam(required = false, defaultValue = "0") Integer isEnergy,
                              @RequestParam(required = false, defaultValue = "0") Integer color,
                              @RequestParam(required = false) String brand,@RequestParam(required = false) String mileage) {
        AppAdCarReq req = new AppAdCarReq();
        req.setToken(token); req.setCheckTime(checkTime);
        req.setPlate(plate); req.setRegisterTime(registerTime);
        req.setType(type);   req.setIsEnergy(isEnergy);
        req.setColor(color); req.setMileage(mileage);
        req.setBrand(brand);
        return appService.addCar(req);
    }

    @ApiOperation(value = "修改车辆信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "oldPlate", value = "旧车牌号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "新车牌号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "color", value = "颜色", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "brand", value = "品牌", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkTime", value = "年检时间", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "registerTime", value = "注册时间", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "isEnergy", value = "是否是新能源 1是 0否", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "mileage", value = "行驶里程", required = false, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/editCar")
    public AppEditCarRsp editCar(@RequestParam String token,@RequestParam(required = false) String checkTime,
                                 @RequestParam String oldPlate,@RequestParam(required = false) String registerTime,
                                 @RequestParam String plate,@RequestParam(required = false, defaultValue = "0") Integer isEnergy,
                                 @RequestParam(required = false) String type,@RequestParam(required = false) String mileage,
                                 @RequestParam(required = false, defaultValue = "0") Integer color,
                                 @RequestParam(required = false) String brand) {
        AppEditCarReq req = new AppEditCarReq();
        req.setToken(token);
        req.setOldPlate(oldPlate);
        req.setPlate(plate);
        req.setType(type);
        req.setColor(color);
        req.setBrand(brand);
        req.setCheckTime(checkTime);
        req.setRegisterTime(registerTime);
        req.setIsEnergy(isEnergy);
        req.setMileage(mileage);
        return appService.editCar(req);
    }

    @ApiOperation(value = "删除车辆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "车牌号", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/deleteCar")
    public AppDeleteCarRsp deleteCar(@RequestParam String token,
                                     @RequestParam String plate) {
        AppDeleteCarReq req = new AppDeleteCarReq();
        req.setToken(token);
        req.setPlate(plate);
        return appService.deleteCar(req);
    }

    @ApiOperation(value = "查询自己的车辆")
    @PostMapping(value = "/getCars")
    public AppGetCarsRsp getCars(@RequestParam String token) {
        AppGetCarsReq req = new AppGetCarsReq();
        req.setToken(token);
        return appService.getCars(req);
    }

    @ApiOperation(value = "获取场内车辆")
    @PostMapping(value = "/getInParking")
    public AppGetInParkingRsp getInParking(@RequestParam String token) {
        AppGetInParkingReq req = new AppGetInParkingReq();
        req.setToken(token);
        return appService.getInParking(req);
    }

    @ApiOperation(value = "获取停车费")
    @PostMapping(value = "/getFee")
//    @GetMapping(value = "/getFee")
    public AppGetFeeRsp getFee(@RequestParam String token,
                               @RequestParam String plate) {
        AppGetFeeReq req = new AppGetFeeReq();
        req.setToken(token);
        req.setPlate(plate);
        //req.setOutTime(outTime);
        return appService.getFee(req);
    }

    @ApiOperation(value = "获取停车记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageNum", value = "查询页数，从0开始", required = true, dataType = "int", paramType = "query")
    })
    @PostMapping(value = "/getInOutParking")
    public AppGetInOutParkingRsp getInOutParking(@RequestParam String token,
                                                 @RequestParam int pageNum) {
        AppGetInOutParkingReq req = new AppGetInOutParkingReq();
        req.setToken(token);
        req.setPageNum(pageNum);
        return appService.getInOutParking(req);
    }

    @ApiOperation(value = "车辆锁定或解锁")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "车牌号码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "车辆操作状态：1锁定，0解锁", dataType = "int", paramType = "query")
    })
    @PostMapping(value = "/carLockOrNo")
    public AppCarLockOrNoRsp carLockOrNo(@RequestParam String token,
                                         @RequestParam String plate,
                                         @RequestParam(required = false) Integer status) {
        AppCarLockOrNoReq req = new AppCarLockOrNoReq();
        req.setToken(token);
        req.setPlate(plate);
        req.setStatus(status);
        return appService.carLockOrNo(req);
    }

    @ApiOperation(value = "问题反馈")
    @PostMapping(value = "/feedback")
    public AppFeedbackRsp feedback(@RequestParam String token,
                                   @RequestParam String content) {
        AppFeedbackReq req = new AppFeedbackReq();
        req.setToken(token);
        req.setContent(content);
        return appService.feedback(req);
    }


    @ApiOperation(value = "上传/修改头像")
    @PostMapping(value = "/postPortrait")
    public AppPostPortraitRsp postPortrait(@RequestParam String token,
                                           @RequestParam MultipartFile file) {
        AppPostPortraitReq req = new AppPostPortraitReq();
        req.setToken(token);
        req.setFile(file);
        return appService.postPortrait(req);
    }

    @ApiOperation(value = "获取头像")
    @GetMapping(value = "/getPortrait/{appUserId}")
    public void getPortrait(@PathVariable Integer appUserId, @RequestParam(required = false) String fileName, HttpServletResponse resp) {

        AppGetPortraitReq req = new AppGetPortraitReq();
        req.setAppUserId(appUserId);
        File file = appService.getPortrait(req);
        if (file != null) {
            try {
                InputStream inputStream = new FileInputStream(file);
                OutputStream outputStream = resp.getOutputStream();
                IOUtils.copy(inputStream, outputStream);
                resp.flushBuffer();
                inputStream.close();
            } catch (IOException e) {
                logger.error("app用户("+appUserId+")获取头像异常：{}", e);
            }
        }
    }

    @ApiOperation(value = "获取个人信息（废弃）")
    @PostMapping(value = "/getInfo")
    @Deprecated
    public AppGetInfoRsp getInfo(@RequestParam String token) {

        AppBusinessReq req = new AppBusinessReq();
        req.setToken(token);
        return appService.getInfo(req);
    }

    @ApiOperation(value = "获取个人信息")
    @PostMapping(value = "/getUserInfo")
    public AppGetUserInfoRsp getUserInfo(@RequestParam String token) {
        AppBusinessReq req = new AppBusinessReq();
        req.setToken(token);
        return appService.getUserInfo(req);
    }

    @ApiOperation(value = "获取app违章查询表单界面")
    @PostMapping(value = "/getIllegalQueryForm")
    public AppIllegalQueryFormRsp getIllegalQueryForm(@RequestParam String token,
                                                      @RequestParam String plate) {
        AppIllegalQueryFormReq req = new AppIllegalQueryFormReq();
        req.setToken(token);
        req.setPlate(plate);
        return appService.getIllegalQueryForm(req);
    }

    @ApiOperation(value = "车辆认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "personName", value = "车主姓名",dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "车牌号码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "carcode", value = "车架号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "cardrive", value = "发动机号", dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/carAuth")
    public AppCarAuthRsp carAuth(@RequestParam String token,
                                 @RequestParam String plate,
                                 @RequestParam(required = false) String personName,
                                 @RequestParam(required = false) String carcode,
                                 @RequestParam(required = false) String cardrive) {
        AppCarAuthReq req = new AppCarAuthReq();
        req.setToken(token);
        req.setPlate(plate);
        req.setPersonName(personName);
        req.setCarcode(carcode);
        req.setCardrive(cardrive);
        return appService.carAuth(req);
    }

    @ApiOperation(value = "违章查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "plate", value = "车牌号码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "carcode", value = "车架号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "cardrive", value = "发动机号", dataType = "String", paramType = "query")
    })
    @GetMapping(value = "/illegalQuery")
    public AppIllegalQueryRsp illegalQuery(@RequestParam String token,
                                           @RequestParam String plate,
                                           @RequestParam(required = false) String carcode,
                                           @RequestParam(required = false) String cardrive,
                                           HttpServletResponse response) {
        AppIllegalQueryRsp rsp = new AppIllegalQueryRsp();
        AppIllegalQueryReq req = new AppIllegalQueryReq();
        req.setToken(token);
        req.setPlate(plate);
        req.setCarcode(carcode);
        req.setCardrive(cardrive);
        IllegalQuery illegalQuery = appService.illegalQuery(req);
        rsp.setResult(illegalQuery.getResult());
        rsp.setStrError(illegalQuery.getStrError());
        if (illegalQuery.getResult() == AppBusinessRsp.SUCCESS) {
            try {
                response.sendRedirect(illegalQuery.getUrl());
                return null;
            } catch (IOException e) {
                logger.error("违章查询异常：{}", e);
                rsp.setResult(-1);
                rsp.setStrError("服务器异常！");
                return rsp;
            }
        }
        return rsp;
    }

    @ApiOperation(value = "获取各个链接")
    @PostMapping(value = "/getUrls")
    public AppGetImageUrlsRsp getUrls() {
        return appService.getUrls();
    }

    @ApiOperation(value = "获取各个链接和md5")
    @ApiImplicitParam(name = "urlType", value = "链接类型：1-启动页，2-首页轮播图", required = true, dataType = "int", paramType = "query")
    @PostMapping(value = "/getUrlsAndMd5")
    public AppGetImgUrlsAndMd5Rsp getUrlsAndMd5(@RequestParam int urlType) {
        AppGetImgUrlsAndMd5Req req = new AppGetImgUrlsAndMd5Req();
        req.setUrlType(urlType);
        return appService.getUrlsAndMd5(req);
    }

    @ApiOperation(value = "检查是否需要升级")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "version", value = "版本号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "appId", value = "app编号 1-易停宝 2-商户优惠券 3-手持机 4-服务APP", dataType = "String", paramType = "query")
    })

    @PostMapping(value = "/checkForUpdate")
    public AppCheckForUpdateRsp checkForUpdate(@RequestParam(required = false) String token,
                                               @RequestParam String version,
                                               @RequestParam(required = false, defaultValue = "1") Integer appId,
                                               @RequestParam(required = false, defaultValue = "0") Integer parkingId) {

        AppCheckForUpdateReq req = new AppCheckForUpdateReq();
        req.setToken(token);
        req.setVersion(version);
        req.setAppId(appId);
        return appService.checkForUpdate(req);
    }

    @ApiOperation(value = "下载最新版本的apk")
    @ApiImplicitParam(name = "appId", value = "app编号 1-易停宝 2-商户优惠券 3-手持机 4-服务APP", dataType = "String", paramType = "query")
    @GetMapping(value = "/downloadApk")
    public void downloadApk(HttpServletResponse response,
                            @RequestParam(required = false, defaultValue = "1") Integer appId,
                            @RequestParam(required = false, defaultValue = "0") Integer parkingId) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            File file = new File(basicProperties.getAppApkFilePath());
            if (appId == 2) {
                file = new File(basicProperties.getAppApkFilePathForMerchant());
            } else if (appId == 3) {
                file = new File(basicProperties.getAppApkFilePathForHandset());
            }else if(appId==4){
                file=new File(basicProperties.getAppApkFilePathForSvrApp());
            }
            inputStream = new FileInputStream(file);
            outputStream = response.getOutputStream();
            response.addHeader("Content-Length", inputStream.available() + "");
            response.addHeader("Content-Disposition", "attachment; filename=\""
                    + file.getName() + "\"");
//            IOUtils.copy(inputStream, outputStream);
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int n = 0;
            while (0 < (n = inputStream.read(buffer))) {
                outputStream.write(buffer, 0, n);
                outputStream.flush();
            }
//            response.flushBuffer();
        } catch (IOException e) {
            logger.error("下载最新版本的apk异常：{}", e);
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error("下载最新版本的apk,关闭流异常：{}", e);
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    logger.error("下载最新版本的apk,关闭流异常：{}", e);
                }
            }
        }
    }

    @ApiOperation(value = "下载最新的jar")
    @GetMapping(value = "/downloadJar")
    public void downloadJar(HttpServletResponse response) {
        InputStream inputStream = null;
        try {
            File file = new File(basicProperties.getAppJarFilePath());
            inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            response.addHeader("Content-Length", inputStream.available() + "");
            response.addHeader("Content-Disposition", "attachment; filename=\""
                    + file.getName() + "\"");
            IOUtils.copy(inputStream, outputStream);
            response.flushBuffer();
            inputStream.close();
        } catch (IOException e) {
            logger.error("下载jar异常：{}", e);
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error("下载jar,关闭流异常：{}", e);
                }
            }
        }
    }

    @ApiOperation(value = "上传车辆认证图片")
    @PostMapping(value = "/uploadAuthPic")
    public AppUploadAuthPicRsp uploadAuthPic(@RequestParam String token,
                                             @RequestParam String plate,
                                             @RequestParam MultipartFile file) {
        AppUploadAuthPicReq req = new AppUploadAuthPicReq();
        req.setToken(token);
        req.setPlate(plate);
        req.setFile(file);
        return appService.uploadAuthPic(req);
    }





    @ApiOperation(value = "ios上传app版本")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "version", value = "版本号", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/uploadVersionForIos")
    public AppUploadVersionForIosRsp uploadVersionForIos(@RequestParam String token,
                                                         @RequestParam String version) {

        AppUploadVersionForIosReq req = new AppUploadVersionForIosReq();
        req.setToken(token);
        req.setVersion(version);
        return appService.uploadVersionForIos(req);
    }

    @ApiOperation(value = "获取首页下方广告")
    @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "String", paramType = "query")
    @PostMapping(value = "/getAd")
    public AppGetAdRsp getAd(@RequestParam String token) {

        AppGetAdReq req = new AppGetAdReq();
        req.setToken(token);
        return appService.getAd(req);
    }

    @ApiOperation(value = "获取是否商户扫码车牌汉字")
    @GetMapping("/getConfiguration")
    public RespResult checkPid(Integer paringId) {
        RespResult result= new RespResult();
        Adminpara para = webService.findParaValueByParkingId(paringId);
        Map map = new HashMap();
        //根据pid获取车场信息
        if(para!=null){
            map.put("value",para.getParaValue());
        }else {
            map.put("value","京");
        }
        result.setResult(RespResult.SUCCESS);
        result.setData(map);
        return result;
    }
}
